package com.campus.service.impl;


import com.campus.entry.SysUser;
import com.campus.exception.BusinessException;
import com.campus.pojo.dto.AccountDto;
import com.campus.pojo.dto.ChangePasswordDto;
import com.campus.pojo.dto.LoginUser;
import com.campus.pojo.dto.RegisterDto;
import com.campus.response.Code;
import com.campus.response.ResultCode;
import com.campus.service.AccountService;
import com.campus.service.SysUserService;
import com.campus.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static net.sf.jsqlparser.util.validation.metadata.NamedObject.role;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 登录
     * @param account
     * @return token
     */

    @Override
    public Map<String, String> login(AccountDto account) {
        //封装用户名和密码
    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
            = new UsernamePasswordAuthenticationToken(account.getLoginName(),account.getPassword());

    Authentication authenticate = null;
        try {
            authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        } catch (AuthenticationException e) {
            throw new BusinessException(Code.ERROR_CODE,e.getMessage());
        }
    //获取Uer对象
    LoginUser loginUser =(LoginUser)authenticate.getPrincipal();
    if(Objects.isNull(loginUser)){
        throw new BusinessException(ResultCode.ERROR_USERNAME_PASSWORD);
    }
    Integer userId = loginUser.getUser().getId();
    String role=sysUserService.gertRoleById(userId);
    String jwts = jwtUtil.creatJWT(userId,role);
        redisTemplate.opsForValue().set("token:"+userId, jwts,7,TimeUnit.DAYS);
    Map<String,String> map=new HashMap<>();
        map.put("token",jwts);
        map.put("role",role);
        return map;
    }
    @Override
    public void logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Integer userId = (Integer)authentication.getPrincipal();
        redisTemplate.delete("token:"+userId);
    }
    @Override
    public void register(RegisterDto registerDto){
        SysUser sysUserByName = sysUserService.getSysUserByName(registerDto.getLoginName());
        String role=registerDto.getRole();
        if (!Objects.isNull(sysUserByName)){
            throw new BusinessException(ResultCode.ERROR_HAVE_USER);
        }
        String password=bCryptPasswordEncoder.encode(registerDto.getPassword());
        SysUser sysUser=new SysUser()
                .setPassword(password)
                .setLoginName(registerDto.getLoginName())
                .setEmail(registerDto.getEmail());
        sysUserService.saveSysUser(sysUser);
        sysUserService.saveRole(sysUserService.getUserIdByUserName(registerDto.getLoginName()),role);
    }

    @Override
    public void changePassword(ChangePasswordDto changePasswordDto) {
        SysUser sysUser = sysUserService.getSysUserByName(changePasswordDto.getLoginName());
        if (Objects.isNull(sysUser)) {
            throw new BusinessException(ResultCode.NO_REGISTER);
        }
        String password = bCryptPasswordEncoder.encode(changePasswordDto.getPassword());
        sysUser.setPassword(password);
        sysUserService.updateSysUser(sysUser);
    }

    @Override
    public void isRightRole(Integer id,String role) {
        if (!role.equals(sysUserService.gertRoleById(id))){
            throw new BusinessException(ResultCode.ERROR_ROLE);
        }
    }
}
